package com.demo.business.wx;


import com.alibaba.fastjson.JSON;
import com.demo.business.order.OrderDao;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.RefundModel;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.jfinal.kit.StrKit;
import com.tiangong.framework.annotation.OpenApi;
import com.tiangong.framework.bo.CDO;
import com.tiangong.framework.bo.Return;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service("wxPay")
@Slf4j
public class WxPayService {
    @Resource
    OrderDao orderDao;
    private static  String APP_ID="wxec5d6ce83eb754a0";
    private static  String APP_SECRET="80ccc5f086246447b64ef09c5079a056";
    private static  String MCH_ID="1618761841";
    private static  String PARTNER_KEY="b94795748d7347308fd0dbd61bf9f284";
    private static  String CERT_PATH="cert/wxpay/cert.p12";
    private static  String DOMAIN="https://www.verycleaner.com";
    /**
     * 小程序支付
     *
     * @param cdoRequest - orderCode订单id
     * @return
     * @author
     * @create: 2022-02-25 23:30:08
     */
    //http://mytest.zixuejava.com/wxPay/miniAppPay
    @OpenApi
    public Return miniAppPay(CDO cdoRequest) {
       //openId
        //orderCode

        String orderCode=null;

       CDO cdoMapperResult = null;

        String openId = null;
        if (cdoRequest.containsKey("orderCode")) {
            orderCode=cdoRequest.get("orderCode").toString();
            cdoMapperResult = orderDao.getOrderById(Long.valueOf(orderCode));
        }
        if (cdoRequest.containsKey("openId")) {
            openId=cdoRequest.get("openId").toString();
        }
        //需要通过授权来获取openId

        String ip = "127.0.0.1";



      String  notifyUrl = DOMAIN.concat("/rest/v1/wxPay/payNotify");
        Double amount=cdoMapperResult.getDouble("nPayFee");

        String strVal =""+Double.valueOf(amount*100).intValue();


        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(APP_ID)
                .mch_id(MCH_ID)
                .nonce_str(WxPayKit.generateStr())
                .body("商品"+orderCode)
                .attach(DOMAIN)
                .out_trade_no(orderCode)
                .total_fee(strVal)
                .spbill_create_ip(ip)
                .notify_url(notifyUrl)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openId)
                .build()
                .createSign(PARTNER_KEY, SignType.MD5);

        String xmlResult = WxPayApi.pushOrder(false, params);

        log.info(xmlResult);
        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);

        String returnCode = result.get("return_code");
        String returnMsg = result.get("return_msg");
        if (!WxPayKit.codeIsOk(returnCode)) {
            return Return.EXCEPTION.valueOf(returnMsg);
        }
        String resultCode = result.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            return Return.EXCEPTION.valueOf(returnMsg);
        }
        // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
        String prepayId = result.get("prepay_id");
        Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(APP_ID, prepayId,
                PARTNER_KEY, SignType.MD5);
        String jsonStr = JSON.toJSONString(packageParams);
        log.info("小程序支付的参数:" + jsonStr);
        log.info("orderCode=====",orderCode);



        System.out.println("小程序支付的参数:" + jsonStr);
        System.out.println("orderCode====="+orderCode);
        return Return.valueOf(packageParams);
    }




    /**
     * 微信退款
     *
     * @param cdoRequest - orderCode订单id
     * @return
     * @author
     * @create: 2022-02-25 23:30:08
     */
    @OpenApi
    public String refund(CDO cdoRequest) {
        String transactionId=null;
         String outTradeNo=null;

        if (cdoRequest.containsKey("transactionId")) {
            transactionId=cdoRequest.get("transactionId").toString();
        }
        CDO cdoMapperResult = null;
        if (cdoRequest.containsKey("outTradeNo")) {
            outTradeNo=cdoRequest.get("outTradeNo").toString();
            cdoMapperResult = orderDao.getOrderById(Long.valueOf(outTradeNo));

        }

        try {
            log.info("transactionId: {} outTradeNo:{}", transactionId, outTradeNo);

            if (StrKit.isBlank(outTradeNo) && StrKit.isBlank(transactionId)) {
                return "transactionId、out_trade_no二选一";
            }
            WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
            Double amount=cdoMapperResult.getDouble("nPayFee");

            String strVal =""+Double.valueOf(amount*100).intValue();;

            Map<String, String> params = RefundModel.builder()
                    .appid(APP_ID)
                    .mch_id(MCH_ID)
                    .nonce_str(WxPayKit.generateStr())
                    .transaction_id(transactionId)
                    .out_trade_no(outTradeNo)
                    .out_refund_no(WxPayKit.generateStr())
                    .total_fee(strVal)
                    .refund_fee(strVal)
                    .build()
                    .createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5);
            String refundStr = WxPayApi.orderRefund(false, params,CERT_PATH, MCH_ID);


            //todo 新增更新订单逻辑
            log.info("refundStr: {}", refundStr);
            return refundStr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 支付成功回调接口
     * @param
     * @return
     */
    @OpenApi
    public String payNotify(CDO cdoRequest) {
        String xmlMsg = null;
        if (cdoRequest.containsKey("data")) {
            xmlMsg=cdoRequest.get("data").toString();
        }
        log.info("支付通知=" + xmlMsg);
        Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);

        String returnCode = params.get("return_code");


        if (WxPayKit.verifyNotify(params, PARTNER_KEY, SignType.MD5)) {
            if (WxPayKit.codeIsOk(returnCode)) {


                Map<String, String> xml = new HashMap<String, String>(2);
                xml.put("return_code", "SUCCESS");
                xml.put("return_msg", "OK");
                //todo 更新订单状态
                //"lOrderId"
                //nStatus:
                if(Objects.nonNull(params.get("out_trade_no"))) {
                    cdoRequest.set("lOrderId", Integer.valueOf(params.get("out_trade_no")));
                    cdoRequest.set("nStatus", 1);
                    orderDao.updateOrderById(cdoRequest);
                }
                return WxPayKit.toXml(xml);
            }
        }
        return null;
    }


}
